using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Net;
using System.Threading;
using System.Xml;
namespace Microsoft.Phone.Controls.Maps.Core
{
	internal sealed class TfeCoverageMap
	{
		private static readonly object requestLock = new object();
		private static readonly Dictionary<Uri, TfeCoverageMap> instances = new Dictionary<Uri, TfeCoverageMap>();
		private static readonly Dictionary<Uri, Collection<TfeCoverageMapState>> requests = new Dictionary<Uri, Collection<TfeCoverageMapState>>();
		private readonly List<TfeZoomLevelRange> levelMaps;
		private readonly string mapGeneration;
		private readonly int maxTfeZoomLevel;
		private readonly int minTfeZoomLevel;
		public bool Loaded
		{
			get;
			private set;
		}
		public string MapGeneration
		{
			get
			{
				return this.mapGeneration;
			}
		}
		public int MinZoomLevel
		{
			get
			{
				return this.minTfeZoomLevel;
			}
		}
		public int MaxZoomLevel
		{
			get
			{
				return this.maxTfeZoomLevel;
			}
		}
		internal TfeCoverageMap(XmlReader reader)
		{
			this.levelMaps = new List<TfeZoomLevelRange>();
			if (reader != null)
			{
				this.Loaded = TfeCoverageMapParser.Parse(reader, this.levelMaps, out this.mapGeneration, out this.minTfeZoomLevel, out this.maxTfeZoomLevel);
				if (this.levelMaps.get_Count() == 0)
				{
					this.Loaded = false;
					return;
				}
			}
			else
			{
				this.Loaded = false;
			}
		}
		public static void GetInstance(Uri coverageMapUri, TfeCoverageMapCallback callback)
		{
			TfeCoverageMap.GetInstance(coverageMapUri, callback, null);
		}
		public static void GetInstance(Uri coverageMapUri, TfeCoverageMapCallback callback, object userState)
		{
			if (coverageMapUri != null && callback != null)
			{
				bool flag = false;
				TfeCoverageMap tfeCoverageMap = null;
				object obj;
				Monitor.Enter(obj = TfeCoverageMap.requestLock);
				try
				{
					if (TfeCoverageMap.instances.ContainsKey(coverageMapUri))
					{
						tfeCoverageMap = TfeCoverageMap.instances.get_Item(coverageMapUri);
					}
					else
					{
						if (!TfeCoverageMap.requests.ContainsKey(coverageMapUri))
						{
							TfeCoverageMap.requests.Add(coverageMapUri, new Collection<TfeCoverageMapState>());
							flag = true;
						}
						TfeCoverageMap.requests.get_Item(coverageMapUri).Add(new TfeCoverageMapState(callback, userState));
					}
				}
				finally
				{
					Monitor.Exit(obj);
				}
				if (tfeCoverageMap != null)
				{
					callback(tfeCoverageMap, userState);
					return;
				}
				if (flag)
				{
					WebClient webClient = new WebClient();
					webClient.add_OpenReadCompleted(new OpenReadCompletedEventHandler(TfeCoverageMap.WebClient_OpenReadCompleted));
					webClient.OpenReadAsync(coverageMapUri, coverageMapUri);
				}
			}
		}
		public bool Covers(QuadKey quadKey)
		{
			return !this.Loaded || this.GetGeneration(quadKey.Key) > 0;
		}
		public int GetMaximumZoomLevel(QuadKey quadKey)
		{
			int maximumZoom = this.minTfeZoomLevel;
			if (this.Loaded)
			{
				for (int i = this.levelMaps.get_Count() - 1; i >= 0; i--)
				{
					if (this.levelMaps.get_Item(i).MaximumZoom > maximumZoom)
					{
						int generation = this.levelMaps.get_Item(i).GetGeneration((quadKey.ZoomLevel < this.levelMaps.get_Item(i).MaximumZoom) ? quadKey.Key : quadKey.Key.Substring(0, this.levelMaps.get_Item(i).MaximumZoom));
						if (generation > 0)
						{
							maximumZoom = this.levelMaps.get_Item(i).MaximumZoom;
						}
					}
				}
			}
			return maximumZoom;
		}
		private static void WebClient_OpenReadCompleted(object sender, OpenReadCompletedEventArgs e)
		{
			Uri uri = e.get_UserState() as Uri;
			if (uri != null)
			{
				TfeCoverageMap tfeCoverageMap;
				if (e.get_Error() == null && e.get_Result() != null)
				{
					XmlReader reader = null;
					try
					{
						reader = XmlReader.Create(e.get_Result());
					}
					catch (XmlException)
					{
					}
					tfeCoverageMap = new TfeCoverageMap(reader);
					if (!tfeCoverageMap.Loaded)
					{
						tfeCoverageMap = null;
					}
				}
				else
				{
					tfeCoverageMap = null;
				}
				object obj;
				Monitor.Enter(obj = TfeCoverageMap.requestLock);
				Collection<TfeCoverageMapState> collection;
				try
				{
					if (tfeCoverageMap != null && !TfeCoverageMap.instances.ContainsKey(uri))
					{
						TfeCoverageMap.instances.Add(uri, tfeCoverageMap);
					}
					if (TfeCoverageMap.requests.ContainsKey(uri))
					{
						collection = TfeCoverageMap.requests.get_Item(uri);
						TfeCoverageMap.requests.Remove(uri);
					}
					else
					{
						collection = new Collection<TfeCoverageMapState>();
					}
				}
				finally
				{
					Monitor.Exit(obj);
				}
				using (IEnumerator<TfeCoverageMapState> enumerator = collection.GetEnumerator())
				{
					while (enumerator.MoveNext())
					{
						TfeCoverageMapState current = enumerator.get_Current();
						current.Callback(tfeCoverageMap, current.UserState);
					}
				}
			}
		}
		private int GetGeneration(string quadcode)
		{
			int num = -1;
			for (int i = 0; i < this.levelMaps.get_Count(); i++)
			{
				num = this.levelMaps.get_Item(i).GetGeneration(quadcode);
				if (num > 0)
				{
					break;
				}
			}
			return num;
		}
	}
}
